package com.example.api.service;

import com.example.api.dto.OptionDTO;
import com.example.api.dto.QuestionDTO;
import com.example.api.entity.Option;
import com.example.api.entity.Question;
import com.example.api.repository.OptionRepository;
import com.example.api.repository.QuestionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class QuestionService {

    @Autowired
    private QuestionRepository questionRepository;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private OptionRepository optionRepository;

    private static final String QUESTION_CACHE_KEY = "questions";
    private static final long CACHE_EXPIRATION_TIME = 10; // 缓存过期时间，单位：分钟

    // 获取所有问题
    public List<QuestionDTO> getAllQuestions() {
        List<QuestionDTO> cachedQuestions = (List<QuestionDTO>) redisTemplate.opsForValue().get(QUESTION_CACHE_KEY);
        if (cachedQuestions != null) {
            return cachedQuestions;
        }

        List<QuestionDTO> questions = questionRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        redisTemplate.opsForValue().set(QUESTION_CACHE_KEY, questions, CACHE_EXPIRATION_TIME, TimeUnit.MINUTES);
        return questions;
    }

    // 根据题目类别ID获取问题
    public List<QuestionDTO> getQuestionsByCategoryId(String categoryId) {
        String cacheKey = "questions:category:" + categoryId;
        List<QuestionDTO> cachedQuestions = (List<QuestionDTO>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedQuestions != null) {
            return cachedQuestions;
        }

        List<QuestionDTO> questions = questionRepository.findByCategoryId(categoryId).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        redisTemplate.opsForValue().set(cacheKey, questions, CACHE_EXPIRATION_TIME, TimeUnit.MINUTES);
        return questions;
    }

    // 将 Question 实体转换为 QuestionDTO
    private QuestionDTO convertToDTO(Question question) {
        QuestionDTO dto = new QuestionDTO();
        dto.setTitle(question.getTitle());
        dto.setTest_type(question.getTestType());
        dto.setAnswer(question.getAnswer());
        dto.setUserAnswer("");
        dto.setUserFavor(false);
        dto.setExplain(question.getExplain());
        dto.setQuestionId(question.getQuestionId());
        dto.setCategoryId(question.getCategoryId());
        
        dto.setOptionList(question.getOptions().stream()
                .map(opt -> {
                    OptionDTO optionDTO = new OptionDTO();
                    optionDTO.setId(opt.getId());  
                    optionDTO.setOptionId(opt.getOptionId());
                    optionDTO.setContent(opt.getContent());
                    return optionDTO;
                })
                .collect(Collectors.toList())
        );
        return dto;
    }

    // 将 QuestionDTO 转换为 Question 实体
    private Question convertToEntity(QuestionDTO questionDTO) {
        Question question = new Question();
        question.setTitle(questionDTO.getTitle());
        question.setTestType(questionDTO.getTest_type());
        question.setAnswer(questionDTO.getAnswer());
        question.setExplain(questionDTO.getExplain());
        question.setCategoryId(questionDTO.getCategoryId());

        List<Option> options = questionDTO.getOptionList().stream()
                .map(optionDTO -> {
                    Option option = new Option();
                    option.setContent(optionDTO.getContent());
                    option.setOptionId(optionDTO.getOptionId()); 
                    option.setQuestion(question); 
                    return option;
                })
                .collect(Collectors.toList());

        question.setOptions(options);
        return question;
    }

    private Option findOrCreateOption(List<Option> options, Integer id) {  
        if (id != null) {
            for (Option option : options) {
                if (option.getId() != null && option.getId().equals(id)) {
                    return option;
                }
            }
        }
        return new Option();
    }

    // 更新现有实体
    private void updateEntityFromDTO(Question existingQuestion, QuestionDTO questionDTO) {
        existingQuestion.setTitle(questionDTO.getTitle());
        existingQuestion.setTestType(questionDTO.getTest_type());
        existingQuestion.setAnswer(questionDTO.getAnswer());
        existingQuestion.setExplain(questionDTO.getExplain());
        existingQuestion.setCategoryId(questionDTO.getCategoryId());

        // 处理 options 集合
        Set<Integer> updatedIds = new HashSet<>();
        for (OptionDTO optionDTO : questionDTO.getOptionList()) {
            Option option = findOrCreateOption(existingQuestion.getOptions(), optionDTO.getId());
            option.setContent(optionDTO.getContent());
            option.setOptionId(optionDTO.getOptionId());
            option.setQuestion(existingQuestion);
            if (option.getId() != null) {
                updatedIds.add(option.getId());
            }
        }

        // 移除不在更新列表中的选项
        existingQuestion.getOptions().removeIf(option -> 
            option.getId() != null && !updatedIds.contains(option.getId())
        );
    }

    // 增加题目
    public void addQuestion(QuestionDTO questionDTO) {
        Question question = convertToEntity(questionDTO);
        questionRepository.save(question);
        clearCache();
    }

    // 删除题目
    public void deleteQuestion(Integer questionId) {
        Optional<Question> optionalQuestion = questionRepository.findById(questionId);
        if (optionalQuestion.isPresent()) {
            questionRepository.deleteById(questionId);
            clearCache();
        } else {
            throw new RuntimeException("题目未找到，ID: " + questionId);
        }
    }

    // 修改题目
    public void updateQuestion(Integer questionId, QuestionDTO questionDTO) {
        Optional<Question> optionalQuestion = questionRepository.findById(questionId);
        if (optionalQuestion.isPresent()) {
            Question existingQuestion = optionalQuestion.get();
            updateEntityFromDTO(existingQuestion, questionDTO);
            questionRepository.save(existingQuestion);
            clearCache();
        } else {
            throw new RuntimeException("题目未找到，ID: " + questionId);
        }
    }

    // 清除缓存
    private void clearCache() {
        redisTemplate.delete(QUESTION_CACHE_KEY);
    }
}
